package com.truyen.persistence.dao.impl;

import java.util.List;

import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;

import com.truyen.persistence.dao.ChapterTamDao;
import com.truyen.persistence.dao.base.GenericJpaBaseDaoImpl;
import com.truyen.persistence.entity.ChapterTam;
import com.truyen.persistence.entity.TruyenKiemHiep;
import com.truyen.persistence.entity.TruyenMa;
import com.truyen.persistence.entity.TruyenTinhCam;
import com.truyen.persistence.entity.TruyenTranh;
import com.truyen.persistence.entity.TruyenTrinhTham;
import com.truyen.utils.PagingInfo;

@Repository
public class ChapterTamDaoImpl extends GenericJpaBaseDaoImpl<ChapterTam, Long>
		implements ChapterTamDao {

	public ChapterTamDaoImpl() {
		super(ChapterTam.class);
	}

	@Override
	public List<ChapterTam> getLstFromSourceBy(int sourceBy) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<String> get("sourceBy"), sourceBy));
		query = query.where(p);
		query.orderBy(critBuilder.asc(entity.get("chapterNumber")));
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		q.setFirstResult(0);
		q.setMaxResults((int) count);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}

	@Override
	public List<ChapterTam> getLstChapterTamByTruyen(TruyenTranh truyen,
			String kwSearch, String sort, String sortBy,
			PagingInfo pInfo) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenTranh> get("truyenTranh"), truyen));
		if(kwSearch!=null && !kwSearch.equals("")){
			kwSearch = kwSearch + "%";
			p = critBuilder.and(p,
					critBuilder.like(entity.<String> get("alias"), kwSearch));
			p = critBuilder.or(p,
					critBuilder.like(entity.<String> get("name"), kwSearch),
					critBuilder.like(entity.<String> get("alias"), "%" + kwSearch),
					critBuilder.like(entity.<String> get("name"), "%" + kwSearch));
		}
		query = query.where(p);
		if(sort.equals("desc")){
			query.orderBy(critBuilder.desc(entity.get(sortBy)));
		}else{
			query.orderBy(critBuilder.asc(entity.get(sortBy)));
		}
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		pInfo.setCount(count);
		pInfo.setTotalPage((int)Math.ceil((double)count/pInfo.getSizePerPage()));		
		q.setFirstResult(pInfo.getStartResult());
		q.setMaxResults(pInfo.getSizePerPage());
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}

	@Override
	public List<ChapterTam> getLstAllChapterTam(String kwSearch, String sort, String sortBy, PagingInfo pInfo) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		if(kwSearch!=null && !kwSearch.equals("")){
			kwSearch = kwSearch + "%";
			p = critBuilder.and(p,
					critBuilder.like(entity.<String> get("alias"), kwSearch));
			p = critBuilder.or(p,
					critBuilder.like(entity.<String> get("name"), kwSearch),
					critBuilder.like(entity.<String> get("alias"), "%" + kwSearch),
					critBuilder.like(entity.<String> get("name"), "%" + kwSearch));
		}
		query = query.where(p);
		if(sort.equals("desc")){
			query.orderBy(critBuilder.desc(entity.get(sortBy)));
		}else{
			query.orderBy(critBuilder.asc(entity.get(sortBy)));
		}
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		pInfo.setCount(count);
		pInfo.setTotalPage((int)Math.ceil((double)count/pInfo.getSizePerPage()));		
		q.setFirstResult(pInfo.getStartResult());
		q.setMaxResults(pInfo.getSizePerPage());
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}


	@Override
	public List<ChapterTam> getByTruyen(TruyenTranh truyen) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenTranh> get("truyenTranh"), truyen));
		query = query.where(p);
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		q.setFirstResult(0);
		q.setMaxResults((int) count);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}

	@Override
	public List<ChapterTam> getByTruyen(TruyenTrinhTham truyen) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenTrinhTham> get("truyenTrinhTham"), truyen));
		query = query.where(p);
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		q.setFirstResult(0);
		q.setMaxResults((int) count);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}

	@Override
	public List<ChapterTam> getByTruyen(TruyenTinhCam truyen) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenTinhCam> get("truyenTinhCam"), truyen));
		query = query.where(p);
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		q.setFirstResult(0);
		q.setMaxResults((int) count);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}

	@Override
	public List<ChapterTam> getByTruyen(TruyenKiemHiep truyen) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenKiemHiep> get("truyenKiemHiep"), truyen));
		query = query.where(p);
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		q.setFirstResult(0);
		q.setMaxResults((int) count);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}
	
	@Override
	public List<ChapterTam> getByTruyen(TruyenMa truyen) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenMa> get("truyenMa"), truyen));
		query = query.where(p);
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		q.setFirstResult(0);
		q.setMaxResults((int) count);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}
	
	@Override
	public ChapterTam findAliasvTruyen(TruyenTranh truyen, String alias) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenTranh> get("truyenTranh"), truyen),
				critBuilder.equal(entity.<String> get("alias"), alias));
		query = query.where(p);
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		q.setFirstResult(0);
		q.setMaxResults(1);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst.get(0) : null;
	}

	@Override
	public ChapterTam findAliasvTruyen(TruyenKiemHiep truyen, String alias) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenKiemHiep> get("truyenKiemHiep"), truyen),
				critBuilder.equal(entity.<String> get("alias"), alias));
		query = query.where(p);
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		q.setFirstResult(0);
		q.setMaxResults(1);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst.get(0) : null;
	}

	@Override
	public ChapterTam findAliasvTruyen(TruyenTrinhTham truyen, String alias) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenTrinhTham> get("truyenTrinhTham"), truyen),
				critBuilder.equal(entity.<String> get("alias"), alias));
		query = query.where(p);
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		q.setFirstResult(0);
		q.setMaxResults(1);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst.get(0) : null;
	}

	@Override
	public ChapterTam findAliasvTruyen(TruyenTinhCam truyen, String alias) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenTinhCam> get("truyenTinhCam"), truyen),
				critBuilder.equal(entity.<String> get("alias"), alias));
		query = query.where(p);
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		q.setFirstResult(0);
		q.setMaxResults(1);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst.get(0) : null;
	}

	@Override
	public List<ChapterTam> getLstFromSourceByVTruyenNotNull(int sourceBy,
			String truyenNotNull) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		if(truyenNotNull.equals("truyenTranh")){
			p = critBuilder.and(p,
					critBuilder.isNotNull(entity.<TruyenTranh> get("truyenTranh")));
		}else if(truyenNotNull.equals("kiemHiep")){
			p = critBuilder.and(p,
					critBuilder.isNotNull(entity.<TruyenKiemHiep> get("truyenKiemHiep")));
		}else if(truyenNotNull.equals("tinhCam")){
			p = critBuilder.and(p,
					critBuilder.isNotNull(entity.<TruyenTinhCam> get("truyenTinhCam")));
		}else{
			p = critBuilder.and(p,
					critBuilder.isNotNull(entity.<TruyenTrinhTham> get("truyenTrinhTham")));
		}
		p = critBuilder.and(p,
				critBuilder.equal(entity.<String> get("sourceBy"), sourceBy));
		query = query.where(p);
		query.orderBy(critBuilder.asc(entity.get("chapterNumber")));
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		q.setFirstResult(0);
		q.setMaxResults((int) count);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}

	@Override
	public List<ChapterTam> getLstChapterTamByTruyen(TruyenKiemHiep truyen,
			String kwSearch, String sort, String sortBy, PagingInfo pInfo) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenKiemHiep> get("truyenKiemHiep"), truyen));
		if(kwSearch!=null && !kwSearch.equals("")){
			kwSearch = kwSearch + "%";
			p = critBuilder.and(p,
					critBuilder.like(entity.<String> get("alias"), kwSearch));
			p = critBuilder.or(p,
					critBuilder.like(entity.<String> get("name"), kwSearch),
					critBuilder.like(entity.<String> get("alias"), "%" + kwSearch),
					critBuilder.like(entity.<String> get("name"), "%" + kwSearch));
		}
		query = query.where(p);
		if(sort.equals("desc")){
			query.orderBy(critBuilder.desc(entity.get(sortBy)));
		}else{
			query.orderBy(critBuilder.asc(entity.get(sortBy)));
		}
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		pInfo.setCount(count);
		pInfo.setTotalPage((int)Math.ceil((double)count/pInfo.getSizePerPage()));		
		q.setFirstResult(pInfo.getStartResult());
		q.setMaxResults(pInfo.getSizePerPage());
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}

	@Override
	public List<ChapterTam> getLstChapterTamByTruyen(TruyenTinhCam truyen,
			String kwSearch, String sort, String sortBy, PagingInfo pInfo) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenTinhCam> get("truyenTinhCam"), truyen));
		if(kwSearch!=null && !kwSearch.equals("")){
			kwSearch = kwSearch + "%";
			p = critBuilder.and(p,
					critBuilder.like(entity.<String> get("alias"), kwSearch));
			p = critBuilder.or(p,
					critBuilder.like(entity.<String> get("name"), kwSearch),
					critBuilder.like(entity.<String> get("alias"), "%" + kwSearch),
					critBuilder.like(entity.<String> get("name"), "%" + kwSearch));
		}
		query = query.where(p);
		if(sort.equals("desc")){
			query.orderBy(critBuilder.desc(entity.get(sortBy)));
		}else{
			query.orderBy(critBuilder.asc(entity.get(sortBy)));
		}
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		pInfo.setCount(count);
		pInfo.setTotalPage((int)Math.ceil((double)count/pInfo.getSizePerPage()));		
		q.setFirstResult(pInfo.getStartResult());
		q.setMaxResults(pInfo.getSizePerPage());
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}

	@Override
	public List<ChapterTam> getLstChapterTamByTruyen(TruyenTrinhTham truyen,
			String kwSearch, String sort, String sortBy, PagingInfo pInfo) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenTrinhTham> get("truyenTrinhTham"), truyen));
		if(kwSearch!=null && !kwSearch.equals("")){
			kwSearch = kwSearch + "%";
			p = critBuilder.and(p,
					critBuilder.like(entity.<String> get("alias"), kwSearch));
			p = critBuilder.or(p,
					critBuilder.like(entity.<String> get("name"), kwSearch),
					critBuilder.like(entity.<String> get("alias"), "%" + kwSearch),
					critBuilder.like(entity.<String> get("name"), "%" + kwSearch));
		}
		query = query.where(p);
		if(sort.equals("desc")){
			query.orderBy(critBuilder.desc(entity.get(sortBy)));
		}else{
			query.orderBy(critBuilder.asc(entity.get(sortBy)));
		}
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		pInfo.setCount(count);
		pInfo.setTotalPage((int)Math.ceil((double)count/pInfo.getSizePerPage()));		
		q.setFirstResult(pInfo.getStartResult());
		q.setMaxResults(pInfo.getSizePerPage());
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}

	@Override
	public ChapterTam findAliasvTruyen(TruyenMa truyen, String alias) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenMa> get("truyenMa"), truyen),
				critBuilder.equal(entity.<String> get("alias"), alias));
		query = query.where(p);
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		q.setFirstResult(0);
		q.setMaxResults(1);
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst.get(0) : null;
	}

	@Override
	public List<ChapterTam> getLstChapterTamByTruyen(TruyenMa truyen,
			String kwSearch, String sort, String sortBy, PagingInfo pInfo) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ChapterTam> query = critBuilder
				.createQuery(ChapterTam.class);
		Root<ChapterTam> entity = query.from(ChapterTam.class);
		Predicate p = critBuilder.conjunction();
		p = critBuilder.and(p,
				critBuilder.equal(entity.<TruyenMa> get("truyenMa"), truyen));
		if(kwSearch!=null && !kwSearch.equals("")){
			kwSearch = kwSearch + "%";
			p = critBuilder.and(p,
					critBuilder.like(entity.<String> get("alias"), kwSearch));
			p = critBuilder.or(p,
					critBuilder.like(entity.<String> get("name"), kwSearch),
					critBuilder.like(entity.<String> get("alias"), "%" + kwSearch),
					critBuilder.like(entity.<String> get("name"), "%" + kwSearch));
		}
		query = query.where(p);
		if(sort.equals("desc")){
			query.orderBy(critBuilder.desc(entity.get(sortBy)));
		}else{
			query.orderBy(critBuilder.asc(entity.get(sortBy)));
		}
		TypedQuery<ChapterTam> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		pInfo.setCount(count);
		pInfo.setTotalPage((int)Math.ceil((double)count/pInfo.getSizePerPage()));		
		q.setFirstResult(pInfo.getStartResult());
		q.setMaxResults(pInfo.getSizePerPage());
		List<ChapterTam> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}

}
